package com.fortune.cat.config;

import com.fortune.cat.service.UserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.http.HttpCookie;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.DispatcherHandler;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @author zhaozeyang
 * @date 2019/5/6 16:12
 * @description 此处采用最简单的实现，需要扩展根据业务场景来定
 */
@Component
public class LoginFilter implements WebFilter {

    private final UserService userService;

    public final static String USER_ID = "userId";

    private final static List<String> skip_url = new ArrayList<String>() {{
        add("/login");
        add("/fortune/cat/user/login");
    }};

    private final ObjectProvider<DispatcherHandler> dispatcherHandlerProvider;

    private volatile DispatcherHandler dispatcherHandler;

    public LoginFilter(UserService userService, ObjectProvider<DispatcherHandler> dispatcherHandlerProvider) {
        this.userService = userService;
        this.dispatcherHandlerProvider = dispatcherHandlerProvider;
    }

    private DispatcherHandler getDispatcherHandler() {
        if (dispatcherHandler == null) {
            dispatcherHandler = dispatcherHandlerProvider.getIfAvailable();
        }

        return dispatcherHandler;
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
        //判断是不是登录接口
        String path = exchange.getRequest().getPath().value();
        if (skip_url.contains(path)||path.startsWith("/assets")) {
            return chain.filter(exchange);
        }
        //判断是否登录
        String userId = exchange.getRequest().getQueryParams().getFirst(USER_ID);
        if (StringUtils.isBlank(userId)) {
            userId = exchange.getRequest().getHeaders().getFirst(USER_ID);
        }
        if (StringUtils.isBlank(userId)) {
            HttpCookie httpCookie = exchange.getRequest().getCookies().getFirst(USER_ID);
            if (Objects.nonNull(httpCookie)) {
                userId = httpCookie.getValue();
            }
        }
        if (StringUtils.isBlank(userId)) {
            return this.getDispatcherHandler().handle(exchange.mutate().request(exchange.getRequest().mutate().path("/login")
                    .method(HttpMethod.GET)
                    .build()).build());
        }
        //设置user
        userService.setUser(userId);
        return chain.filter(exchange);
    }
}
